home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / pmode / pmode30b / pm24sh.asm < prev    next >
Assembly Source File  |  1994-05-29  |  37KB  |  1,082 lines

  1. ; PMODE v2.4 shell for PMODE v3.0
  2. ; By Tran (a.k.a. Thomas Pytel).
  3.  
  4.         .386p
  5.  
  6. LOWMIN          = 0             ; minimum free low memory (in K)
  7. EXTMIN          = 0             ; minimum free extended memory (in K)
  8. SELECTORS       = 8             ; extra selectors for allocation
  9. STAKMAIN        = 100h          ; main execution stream stack size (in para)
  10. STAKRMODE       = 10h           ; real mode call stack size (in para)
  11. STAKPMODE       = 20h           ; protected mode call stack size (in para)
  12. MODENESTING     = 8             ; max number of nested mode switches
  13.  
  14. RMODENUM        = (MODENESTING+1) shr 1
  15. PMODENUM        = MODENESTING shr 1
  16. STAKSIZE        = STAKMAIN+(PMODENUM*STAKPMODE)+(RMODENUM*STAKRMODE)
  17.  
  18. .errnz STAKSIZE gt 0fffh        ; error if stack greater than 64k
  19.  
  20. PMODE_TEXT      segment para public use16 'CODE'
  21. PMODE_TEXT      ends
  22. code16  segment para public use16
  23. code16  ends
  24. code32  segment para public use32
  25. code32  ends
  26. codeend segment para stack use32 'stack'
  27. codeend ends
  28.  
  29. extrn   _pm_info:far, _pm_init:far
  30. extrn   _pm_pagetables:byte, _pm_selectors:word, _pm_rmstacklen:word
  31. extrn   _pm_pmstacklen:word, _pm_rmstacks:byte, _pm_pmstacks:byte
  32. extrn   _pm_callbacks:byte
  33.  
  34. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  35. ; Real mode and 16bit code
  36. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  37. code16  segment para public use16
  38.         assume cs:code16, ds:code16
  39.         org 0
  40.  
  41. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  42. ; 16 bit common system data
  43. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  44. exiterrmsgtbl   dw      errmsg0,errmsg2,d_errmsg0,errmsg4,d_errmsg3,d_errmsg1
  45.  
  46. errmsg0         db      '386 or better not detected!!!',7,'$'
  47. errmsg1         db      'Not enough low memory!!!',7,'$'
  48. errmsg2         db      'System is already in V86 mode, and no VCPI or DPMI found!!!',7,'$'
  49. errmsg3         db      'Not enough extended memory!!!',7,'$'
  50. errmsg4         db      'Couldn''t enable A20 gate!!!',7,'$'
  51. errmsg5         db      'Extended memory allocation failure. (weird eh???)',7,'$'
  52.  
  53. nullint         db      0cfh            ; IRET instruction
  54. exitrout        dw      exit            ; exit routine, modified if XMS, VCPI
  55. pmbuflen        dw      ?               ; length of PMODE low buffer
  56.  
  57. savedstakoff    dw      ?               ; current saved stack offset
  58. savedstakseg    dw      ?               ; current saved stack segment
  59.  
  60. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  61. ; 16 bit common system code
  62. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  63. ;═════════════════════════════════════════════════════════════════════════════
  64. intreal:                                ; real mode int, load FS and GS here
  65.         pushf
  66. ;-----------------------------------------------------------------------------
  67. callreal:                               ; real mode call, load FS and GS here
  68.         push cs
  69.         push offset icreald
  70.         mov fs,cs:v86r_fs
  71.         mov gs,cs:v86r_gs
  72.         mov eax,cs:v86r_eax
  73.         mov ecx,cs:v86r_ecx
  74.         mov edx,cs:v86r_edx
  75.         mov ebx,cs:v86r_ebx
  76.         mov esi,cs:v86r_esi
  77.         mov edi,cs:v86r_edi
  78.         mov ebp,cs:v86r_ebp
  79. ;-----------------------------------------------------------------------------
  80. icreal:                                 ; real mode int, call, or IRQ
  81.         db 66h,68h              ; PUSH destination addx
  82. icrealm1        dd      ?       ;
  83. icrealm0        db      ?       ; CLI or STI
  84.         retf
  85. ;-----------------------------------------------------------------------------
  86. icreald:                                ; done with real int or call
  87.         cli
  88.         pushf
  89.         pop cs:v86r_flags
  90.         mov cs:v86r_eax,eax
  91.         mov cs:v86r_ecx,ecx
  92.         mov cs:v86r_edx,edx
  93.         mov cs:v86r_ebx,ebx
  94.         mov cs:v86r_esi,esi
  95.         mov cs:v86r_edi,edi
  96.         mov cs:v86r_ebp,ebp
  97.         mov cs:v86r_ds,ds
  98.         mov cs:v86r_es,es
  99.         mov cs:v86r_fs,fs
  100.         mov cs:v86r_gs,gs
  101. icreald2:
  102.         mov ax,cs
  103.         mov ds,ax
  104. icrealm2        label word              ; return to pmode modifiable to JMP
  105. ;-----------------------------------------------------------------------------
  106.         mov ebx,ds:dp_savedstakoff      ; DPMI return to pmode
  107.         mov dx,ds:dp_savedstaksel
  108.         mov edi,offset dp_int3_d
  109.         mov si,ds:_selcode
  110.         mov cx,dx
  111.         mov ax,ds:_seldata
  112.         jmp ds:d_switchaddx
  113. ;═════════════════════════════════════════════════════════════════════════════
  114. int32:                                  ; real mode INT32: EDX=off
  115.         pushad
  116.         push ds es fs gs
  117.         cli
  118.         mov ax,cs
  119.         mov ds,ax
  120.         mov ds:p_cpmodem0,edx
  121.         mov al,[esp+45]
  122.         shr al,1
  123.         and al,1
  124.         add al,0fah
  125.         mov ds:p_cpmodem1,al
  126.         push savedstakoff
  127.         push savedstakseg
  128.         movzx ebx,ds:nextmodestack
  129.         lea eax,[ebx-STAKPMODE*16]
  130.         mov ds:nextmodestack,ax
  131.         add ebx,ds:realstackbase
  132.         mov savedstakseg,ss
  133. int32m0         label   word            ; jump to pmode, modifiable
  134. ;-----------------------------------------------------------------------------
  135.         sub sp,ds:dp_savelen
  136.         mov savedstakoff,sp
  137.         mov ax,ss                       ; DPMI jump to pmode
  138.         mov es,ax
  139.         mov di,sp
  140.         xor al,al
  141.         call d_saveaddx
  142.         mov ax,ds:_seldata
  143.         mov cx,ax
  144.         mov dx,ax
  145.         mov edi,offset p_cpmode0
  146.         mov si,ds:_selcode
  147.         jmp ds:d_switchaddx
  148. ;═════════════════════════════════════════════════════════════════════════════
  149. int32d0:                                ; DPMI done with pmode call
  150.         mov di,sp
  151.         mov al,1
  152.         call d_saveaddx
  153.         add sp,ds:dp_savelen
  154. ;-----------------------------------------------------------------------------
  155. int32d2:                                ; done from all
  156.         pop savedstakseg
  157.         pop savedstakoff
  158.         add ds:nextmodestack,STAKPMODE*16
  159.         mov bx,ds:v86r_flags
  160.         mov ax,[esp+44]
  161.         and ax,not 8d5h
  162.         and bx,8d5h
  163.         or ax,bx
  164.         mov [esp+44],ax
  165.         pop gs fs es ds
  166.         popad
  167.         iret
  168. ;─────────────────────────────────────────────────────────────────────────────
  169. pregetlomem:                            ; Get low memory or abort
  170.         add eax,ds:_lomembase
  171.         mov ebx,ds:_lomemtop
  172.         cmp eax,ebx
  173.         ja short pregetlomema
  174.         mov ecx,eax
  175.         xchg eax,ds:_lomembase
  176.         sub ebx,ecx
  177.         cmp ebx,LOWMIN*1024
  178.         jb short pregetlomema
  179.         ret
  180. pregetlomema:
  181.         mov dx,offset errmsg1
  182. ;─────────────────────────────────────────────────────────────────────────────
  183. exit16err:                              ; Exit program with message
  184.         mov ah,9
  185.         int 21h
  186.         jmp exitrout
  187. ;-----------------------------------------------------------------------------
  188. exit:                                   ; Guess what???
  189.         mov ah,4ch
  190.         mov al,ds:_exitcode
  191.         int 21h
  192. ;═════════════════════════════════════════════════════════════════════════════
  193. start16:                                ; Program begins here
  194.         cli
  195.         cld
  196.         push cs
  197.         pop ds
  198.  
  199.         push es                         ; set up PMODE variables
  200.         mov ax,PMODE_TEXT
  201.         mov es,ax
  202.         mov es:_pm_pagetables,(EXTMIN/4096)+1
  203.         mov es:_pm_selectors,3+SELECTORS
  204.         mov es:_pm_rmstacklen,STAKRMODE
  205.         mov es:_pm_rmstacks,MODENESTING/2
  206.         xor eax,eax
  207.         mov es:_pm_pmstacklen,ax
  208.         mov es:_pm_pmstacks,al
  209.         mov es:_pm_callbacks,al
  210.         pop es
  211.  
  212.         call _pm_info                   ; get protected mode info
  213.         mov si,ax
  214.         mov dx,exiterrmsgtbl[si]
  215.         jc exit16err                    ; if error, exit with error message
  216.  
  217.         mov pmbuflen,bx
  218.         or ds:_sysbyte0,ch              ; set system type byte
  219.  
  220.         mov ax,es                       ; set up a bunch of pointers
  221.         movzx eax,ax
  222.         shl eax,4
  223.         mov ds:_pspa,eax
  224.         mov eax,code16
  225.         shl eax,4
  226.         mov ds:_code16a,eax
  227.         or dword ptr ds:gdt32code16[2],eax
  228.         or dword ptr ds:gdt32data16[2],eax
  229.         mov ebx,code32
  230.         shl ebx,4
  231.         mov ds:_code32a,ebx
  232.         or dword ptr ds:gdt32code32[2],ebx
  233.         or dword ptr ds:gdt32data32[2],ebx
  234.         mov eax,codeend
  235.         shl eax,4
  236.         sub eax,ebx
  237.         mov ds:_lomembase,eax
  238.         mov ds:realstackbase,eax
  239.         movzx eax,word ptr es:[2]
  240.         shl eax,4
  241.         sub eax,ebx
  242.         mov ds:_lomemtop,eax
  243.  
  244.         mov eax,STAKSIZE*16             ; get stack memory
  245.         call pregetlomem
  246.  
  247.         push es                         ; save PSP seg (DPMI chek kills ES)
  248.         pop fs
  249.  
  250.         jmp d_start
  251.  
  252. ;─────────────────────────────────────────────────────────────────────────────
  253. ; BL=low PIC val, BH=high PIC val
  254. setintslots:                            ; set int nums in table to PIC vals
  255.         mov edi,offset ds:intslottbl
  256.         mov cl,8
  257. setintslotsl0:
  258.         mov [di],bl
  259.         inc di
  260.         inc bl
  261.         dec cl
  262.         jnz setintslotsl0
  263.         mov cl,8
  264. setintslotsl1:
  265.         mov [di],bh
  266.         inc di
  267.         inc bh
  268.         dec cl
  269.         jnz setintslotsl1
  270.         ret
  271.  
  272. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  273. ; 16 bit DPMI system data
  274. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  275. d_errmsg0       db      'DPMI host is not 32bit!!!',7,'$'
  276. d_errmsg1       db      'Ran out of DPMI descriptors!!!',7,'$'
  277. d_errmsg2       db      'Couldn''t set DPMI descriptors as needed!!!',7,'$'
  278. d_errmsg3       db      'Couldn''t enter 32bit protected mode!!!',7,'$'
  279.  
  280. d_memhandlep    db      0               ; 1=memory handle present, 0=not
  281.  
  282. d_enterpmode    dw      ?,?             ; DPMI switch to pmode addx
  283. d_pspsel        dw      ?               ; stupid PSP selector
  284. d_oldenvsegsel  dw      ?               ; stupid selector we dont want
  285.  
  286. d_memhandle     dw      ?,?             ; DPMI memory block handle
  287.  
  288. d_switchaddx    dd      ?               ; switch to pmode addx
  289. d_saveaddx      dd      ?               ; save/restore state addx
  290.  
  291. d_nintoff       dd      offset dp_irq0,offset dp_irq1,offset dp_irq2,offset dp_irq3
  292.                 dd      offset dp_irq4,offset dp_irq5,offset dp_irq6,offset dp_irq7
  293.                 dd      offset dp_irq8,offset dp_irq9,offset dp_irqa,offset dp_irqb
  294.                 dd      offset dp_irqc,offset dp_irqd,offset dp_irqe,offset dp_irqf
  295.                 dd      offset dp_int33,offset dp_int32,offset dp_int33,offset dp_int32
  296. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  297. ; 16 bit DPMI system code
  298. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  299. ;═════════════════════════════════════════════════════════════════════════════
  300. d_retreal:                              ; Return to real mode
  301.         cmp d_memhandlep,0              ; free memory block if present
  302.         je short d_retrealf0
  303.         mov di,d_memhandle[0]
  304.         mov si,d_memhandle[2]
  305.         mov ax,502h
  306.         int 31h
  307. d_retrealf0:
  308.         mov ax,205h                     ; restore all int vektorz needed
  309.         mov edi,19
  310. d_retreall0:
  311.         mov bl,ds:intslottbl[edi]
  312.         lea ebp,[edi*2+edi]
  313.         mov edx,dword ptr ds:dp_ointbuf[ebp*2]
  314.         mov cx,word ptr ds:dp_ointbuf[ebp*2+4]
  315.         int 31h
  316.         sub di,1
  317.         jnc d_retreall0
  318.         jmp short d_exit
  319. ;─────────────────────────────────────────────────────────────────────────────
  320. d_exit16err:                            ; DPMI Exit with error message
  321.         mov ds:v86r_ds,code16
  322.         mov ds:v86r_ah,9
  323.         mov ax,300h
  324.         mov bx,21h
  325.         xor cx,cx
  326.         mov edi,offset ds:v86r_edi
  327.         push ds
  328.         pop es
  329.         int 31h
  330. ;─────────────────────────────────────────────────────────────────────────────
  331. d_exit:                                 ; DPMI exit to real mode
  332.         mov es,d_pspsel                 ; restore env selector
  333.         mov ax,d_oldenvsegsel
  334.         mov es:[2ch],ax
  335.         jmp exit
  336. ;═════════════════════════════════════════════════════════════════════════════
  337. d_start:                                ; Start in a crappy DPMI system
  338.         movzx eax,pmbuflen              ; get mem for DPMI low memory block
  339.         shl eax,4
  340.         call pregetlomem
  341.         shr eax,4
  342.         add ax,code32
  343.         mov es,ax
  344.  
  345.         call _pm_init                   ; switch to protected mode
  346.  
  347.         cli                             ; I don't trust myself
  348.         mov dx,offset d_errmsg3
  349.         jc exit16err
  350.         mov ds:v86r_dx,offset d_errmsg1 ; prepare for abort maybe
  351.         pop ax                          ; swap old env seg with selector
  352.         xchg ax,es:[2ch]
  353.         mov d_oldenvsegsel,ax
  354.         mov d_pspsel,es                 ; store stupid selectors
  355.         mov ds:data16sel,ds
  356.         mov ds:code16sel,cs
  357.  
  358.         push ds                         ; no more need for PSP
  359.         pop es
  360.         mov ax,3                        ; get selector increment value
  361.         int 31h
  362.         mov bx,ax
  363.         xor ax,ax                       ; get needed selectors
  364.         mov cx,3+SELECTORS
  365.         int 31h
  366.         jc d_exit16err
  367.  
  368.         mov si,ax                       ; set up descriptors
  369.         mov ds:_selcode,ax
  370.         lea ecx,[eax+ebx]
  371.         mov ds:_seldata,cx
  372.         lea ebp,[ecx+ebx]
  373.         mov ds:_selzero,bp
  374.         lea eax,[ebp+ebx]
  375. if SELECTORS ne 0
  376.         mov ds:selectorbase,ax
  377.         mov ds:selectorinc,bx
  378. endif
  379.         mov ds:v86r_dx,offset d_errmsg2
  380.  
  381.         mov ax,cs                       ; set DPL fields of descriptors
  382.         lar ax,ax
  383.         and ah,60h
  384.         or byte ptr ds:gdt32code32[5],ah
  385.         or byte ptr ds:gdt32data32[5],ah
  386.         or byte ptr ds:gdt32zero32[5],ah
  387.  
  388.         mov ax,0ch                      ; set descriptors from GDT
  389.         mov bx,si
  390.         mov edi,offset ds:gdt32code32
  391.         int 31h
  392.         jc d_exit16err
  393.         mov bx,cx
  394.         mov edi,offset ds:gdt32data32
  395.         int 31h
  396.         jc d_exit16err
  397.         mov bx,bp
  398.         mov edi,offset ds:gdt32zero32
  399.         int 31h
  400.         jc d_exit16err
  401. if SELECTORS ne 0
  402.         mov bx,ds:selectorbase          ; set up extra allocatable selectors
  403.         mov dx,SELECTORS
  404. d_startl1:
  405.         int 31h
  406.         jc d_exit16err
  407.         add bx,ds:selectorinc
  408.         dec dx
  409.         jnz d_startl1
  410. endif
  411.         mov es,cx                       ; ES, FS, and GS what they should be
  412.         mov fs,cx
  413.         mov gs,bp
  414.  
  415.         mov edi,ds:_lomembase           ; chek and get extended memory
  416.         mov eax,ds:_lomemtop
  417.         sub eax,edi
  418.         cmp eax,48
  419.         mov ds:v86r_dx,offset errmsg1
  420.         jb d_exit16err
  421.         mov ax,500h
  422.         int 31h
  423.         mov eax,es:[edi]
  424.         lea edx,[eax+1024]
  425.         mov ds:v86r_dx,offset errmsg3
  426. d_startl2:
  427.         sub edx,1024
  428.         jnc short d_startf2
  429.         xor edx,edx
  430. d_startf2:
  431.         cmp edx,EXTMIN*1024
  432.         jb d_exit16err
  433.         or edx,edx
  434.         jz short d_startf1
  435.         mov cx,dx
  436.         shld ebx,edx,16
  437.         mov ax,501h
  438.         int 31h
  439.         jc d_startl2
  440.         mov ds:d_memhandle[0],di
  441.         mov ds:d_memhandle[2],si
  442.         mov ds:d_memhandlep,1
  443.  
  444.         shl ebx,16
  445.         mov bx,cx
  446.         sub ebx,ds:_code32a
  447.         mov ds:_himembase,ebx
  448.         add ebx,edx
  449.         mov ds:_himemtop,ebx
  450. d_startf1:
  451.  
  452.         mov ax,305h                     ; get save/restore state addxs
  453.         int 31h
  454.         mov ds:dp_savelen,ax
  455.         mov dword ptr ds:dp_saveaddx[0],edi
  456.         mov word ptr ds:dp_saveaddx[4],si
  457.         mov word ptr d_saveaddx[0],cx
  458.         mov word ptr d_saveaddx[2],bx
  459.         mov ax,306h                     ; get switch mode addxs
  460.         int 31h
  461.         mov dword ptr ds:dp_switchaddx[0],edi
  462.         mov word ptr ds:dp_switchaddx[4],si
  463.         mov word ptr d_switchaddx[0],cx
  464.         mov word ptr d_switchaddx[2],bx
  465.  
  466.         mov ax,400h                     ; set IRQ handlers to PIC values
  467.         int 31h
  468.         xchg dl,dh
  469.         mov bx,dx
  470.         call setintslots
  471.  
  472.         mov ah,2                        ; backup and set all int vektorz
  473.         mov si,ds:_selcode
  474.         mov edi,19
  475. d_startl0:
  476.         mov bl,ds:intslottbl[edi]
  477.         mov al,4
  478.         int 31h
  479.         lea ebp,[edi*2+edi]
  480.         mov dword ptr ds:dp_ointbuf[ebp*2],edx
  481.         mov word ptr ds:dp_ointbuf[ebp*2+4],cx
  482.         mov al,5
  483.         mov edx,d_nintoff[edi*4]
  484.         mov cx,si
  485.         int 31h
  486.         sub di,1
  487.         jnc d_startl0
  488.  
  489.         mov ax,es                       ; set up needed regs & go on to 32bit
  490.         mov ss,ax
  491.         add esp,ds:realstackbase
  492.         mov ds,ax
  493.         push dword ptr cs:_selcode
  494.         push offset p_start
  495.         db 66h,0cbh             ; 32bit RETF
  496.  
  497. code16  ends
  498.  
  499. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  500. ; 32bit pmode code
  501. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  502. code32  segment para public use32
  503.         assume cs:code32, ds:code32
  504.         org 0
  505.  
  506. extrn   _main:near
  507.  
  508. public  _exit, _ret, _getmem, _getlomem, _gethimem, _lomemsize, _himemsize
  509. public  _getirqmask, _setirqmask, _getselector, _freeselector, _rmpmirqset
  510. public  _rmpmirqfree
  511.  
  512. public  v86r_eax, v86r_ebx, v86r_ecx, v86r_edx, v86r_esi, v86r_edi, v86r_ebp
  513. public  v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp
  514. public  v86r_al, v86r_ah, v86r_bl, v86r_bh, v86r_cl, v86r_ch, v86r_dl, v86r_dh
  515. public  v86r_ds, v86r_es, v86r_fs, v86r_gs
  516. public  _selcode, _seldata, _selzero, _lomembase, _lomemtop, _himembase
  517. public  _himemtop, _pspa, _code16a, _code32a, _getirqvect, _setirqvect
  518. public  _sysbyte0, _irqmode, _setselector, _exitcode
  519. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  520. ; 32 bit common system data
  521. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  522. _lomembase      dd      ?               ; low mem base for allocation
  523. _lomemtop       dd      ?               ; top of low mem
  524. _himembase      dd      0               ; high mem base for allocation
  525. _himemtop       dd      0               ; top of high mem
  526. _pspa           dd      ?               ; offset of start of PSP from 0
  527. _code16a        dd      ?               ; offset of start of 16bit code from 0
  528. _code32a        dd      ?               ; offset of start of 32bit code from 0
  529. _selcode        dw      8               ; code segment selector
  530. _seldata        dw      10h             ; data segment alias for code
  531. _selzero        dw      18h             ; data segment starting at 0:0
  532. _irqmode        dw      0ffffh          ; IRQ mode bits: 0=normal, 1=safe
  533.                 db      0ffh            ; misc byte, has to follow _irqmode
  534. _sysbyte0       db      0               ; system bits:
  535.                                         ;  0-1: 0=raw, 1=XMS, 2=VCPI, 3=DPMI
  536. _exitcode       db      0               ; exit code for int21h ah=4ch
  537.  
  538. align 4
  539. _getirqvect     dd      dp_getirqvect   ; get IRQ handler offset routine addx
  540. _setirqvect     dd      dp_setirqvect   ; set IRQ handler offset routine addx
  541. _setselector    dd      dp_setselector  ; set a selector addx offset addx
  542.  
  543. gdt32           dq      0
  544. gdt32code32     db      0ffh,0ffh,0,0,0,9ah,0cfh,0
  545. gdt32data32     db      0ffh,0ffh,0,0,0,92h,0cfh,0
  546. gdt32zero32     db      0ffh,0ffh,0,0,0,92h,0cfh,0
  547. gdt32code16     db      0ffh,0ffh,0,0,0,9ah,0,0
  548. gdt32data16     db      0ffh,0ffh,0,0,0,92h,0,0
  549. gdt32task       db      0ffh,0ffh,0,0,0,89h,0,0
  550. gdt32vcpi       dq      3 dup(?)
  551. if SELECTORS ne 0
  552. gdt32free       db      SELECTORS dup(0ffh,0ffh,0,0,0,92h,0cfh,0)
  553. endif
  554.  
  555. v86r_edi        label   dword           ; vregs for pmode<>real communication
  556. v86r_di         dw      ?, ?            ;  needz to stay this way cuz its a
  557. v86r_esi        label   dword           ;  stupid DPMI structure thingy
  558. v86r_si         dw      ?, ?
  559. v86r_ebp        label   dword
  560. v86r_bp         dw      ?, ?
  561.                 dd      0
  562. v86r_ebx        label   dword
  563. v86r_bx         label   word
  564. v86r_bl         db      ?
  565. v86r_bh         db      ?, ?,?
  566. v86r_edx        label   dword
  567. v86r_dx         label   word
  568. v86r_dl         db      ?
  569. v86r_dh         db      ?, ?,?
  570. v86r_ecx        label   dword
  571. v86r_cx         label   word
  572. v86r_cl         db      ?
  573. v86r_ch         db      ?, ?,?
  574. v86r_eax        label   dword
  575. v86r_ax         label   word
  576. v86r_al         db      ?
  577. v86r_ah         db      ?, ?,?
  578. v86r_flags      dw      ?
  579. v86r_es         dw      ?
  580. v86r_ds         dw      ?
  581. v86r_fs         dw      ?
  582. v86r_gs         dw      ?
  583.                 dd      0,0
  584.  
  585. oint1bvect      dd      ?               ; old real int 1bh vektor (ctrl+break)
  586. oint32vect      dd      ?               ; old real int 32h vector
  587. oirqmask        dw      ?               ; old port 21h and 0a1h masks
  588. intslottbl      db      8,9,0ah,0bh,0ch,0dh,0eh,0fh,70h,71h,72h,73h,74h,75h,76h,77h
  589.                 db      35h,34h,33h,32h,31h,0,1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh
  590.  
  591. if SELECTORS ne 0
  592. selectorbase    dw      50h
  593. selectorinc     dw      8
  594. selectorfree    db      SELECTORS dup(0)
  595. endif
  596.  
  597. code16off       dw      d_retreal       ; offset in 16bit of exit function
  598. code16sel       dw      20h             ; 16bit pmode code selector
  599. data16sel       dw      28h             ; 16bit pmode data selector
  600.  
  601. nextmodestack   dw      (STAKSIZE-STAKMAIN)*16  ; stack for next mode switch
  602. realstackbase   dd      ?               ; linear ptr to beginning of codeend
  603.  
  604. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  605. ; 32 bit common system code
  606. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  607. ;═════════════════════════════════════════════════════════════════════════════
  608. p_cpmode0:                              ; call pmode, load FS and GS
  609.         mov fs,_seldata
  610.         mov gs,_selzero
  611. ;-----------------------------------------------------------------------------
  612. p_cpmode:                               ; call pmode routine from real
  613.         push offset p_cpmoded
  614.         cld
  615.         mov eax,v86r_eax
  616.         mov ecx,v86r_ecx
  617.         mov edx,v86r_edx
  618.         mov ebx,v86r_ebx
  619.         mov esi,v86r_esi
  620.         mov edi,v86r_edi
  621.         mov ebp,v86r_ebp
  622.         db 68h                  ; PUSH destination address
  623. p_cpmodem0      dd      ?       ;
  624. p_cpmodem1      db      ?       ; CLI or STI
  625.         ret
  626. ;-----------------------------------------------------------------------------
  627. p_cpmoded:                              ; call to pmode done
  628.         cli
  629.         pushf
  630.         pop v86r_flags
  631.         mov v86r_eax,eax
  632.         mov v86r_ecx,ecx
  633.         mov v86r_edx,edx
  634.         mov v86r_ebx,ebx
  635.         mov v86r_esi,esi
  636.         mov v86r_edi,edi
  637.         mov v86r_ebp,ebp
  638.         mov ecx,_code16a
  639. p_cpmodem2        label word            ; return to real, modifiable to JMP
  640. ;-----------------------------------------------------------------------------
  641.         movzx ebx,gs:savedstakoff[ecx]  ; DPMI return to real mode
  642.         mov dx,gs:savedstakseg[ecx]
  643.         mov ax,code16
  644.         mov cx,dx
  645.         mov si,ax
  646.         mov edi,offset int32d0
  647.         jmp dp_switchaddx
  648. ;═════════════════════════════════════════════════════════════════════════════
  649. p_start:                                ; common 32bit start
  650.         mov eax,gs:[1bh*4]              ; neutralize crtl+break
  651.         mov oint1bvect,eax
  652.         db 65h,67h,0c7h,6       ; MOV DWORD PTR GS:[1bh*4],code16:nullint
  653.         dw 1bh*4,nullint,code16 ;
  654.         mov eax,gs:[32h*4]              ; set up for new real mode INT32
  655.         mov oint32vect,eax
  656.         db 65h,67h,0c7h,6       ; MOV DWORD PTR GS:[32h*4],code16:int32
  657.         dw 32h*4,int32,code16   ;
  658.         in al,21h                       ; save old PIC masks
  659.         mov ah,al
  660.         in al,0a1h
  661.         mov oirqmask,ax
  662.         jmp _main                       ; go to main code
  663.  
  664. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  665. ; Allocate any mem, (first cheks low, then high)
  666. ; In:
  667. ;   EAX - size requested
  668. ; Out:
  669. ;   CF=0 - memory allocated
  670. ;   CF=1 - not enough mem
  671. ;   EAX - linear pointer to mem or ?
  672. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  673. _getmem:
  674.         push eax
  675.         call _getlomem
  676.         jnc short getmemd
  677.         pop eax
  678.         jmp short _gethimem
  679. getmemd:
  680.         add esp,4
  681. _ret:                                   ; generic RET instruction
  682.         ret
  683. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  684. ; Allocate some low mem
  685. ; In:
  686. ;   EAX - size requested
  687. ; Out:
  688. ;   CF=0 - memory allocated
  689. ;   CF=1 - not enough mem
  690. ;   EAX - linear pointer to mem or ?
  691. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  692. _getlomem:
  693.         add eax,_lomembase
  694.         cmp eax,_lomemtop
  695.         ja short getmemerr
  696.         xchg eax,_lomembase
  697.         clc
  698.         ret
  699. getmemerr:
  700.         stc
  701.         ret
  702. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  703. ; Allocate some high mem
  704. ; In:
  705. ;   EAX - size requested
  706. ; Out:
  707. ;   CF=0 - memory allocated
  708. ;   CF=1 - not enough mem
  709. ;   EAX - linear pointer to mem or ?
  710. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  711. _gethimem:
  712.         add eax,_himembase
  713.         cmp eax,_himemtop
  714.         ja short getmemerr
  715.         xchg eax,_himembase
  716.         clc
  717.         ret
  718. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  719. ; Get amount of free low mem
  720. ; Out:
  721. ;   EAX - number of bytes free
  722. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  723. _lomemsize:
  724.         mov eax,_lomemtop
  725.         sub eax,_lomembase
  726.         ret
  727. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  728. ; Get amount of free high mem
  729. ; Out:
  730. ;   EAX - number of bytes free
  731. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  732. _himemsize:
  733.         mov eax,_himemtop
  734.         sub eax,_himembase
  735.         ret
  736. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  737. ; Get status of IRQ mask bit
  738. ; In:
  739. ;   BL - IRQ num (0-15)
  740. ; Out:
  741. ;   AL - status: 0=enabled, 1=disabled
  742. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  743. _getirqmask:
  744.         push ax
  745.         in al,0a1h
  746.         mov ah,al
  747.         in al,21h
  748.         xchg cl,bl
  749.         shr ax,cl
  750.         xchg cl,bl
  751.         and al,1
  752.         mov [esp],al
  753.         pop ax
  754.         ret
  755. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  756. ; Set status of IRQ mask bit
  757. ; In:
  758. ;   BL - IRQ num (0-15)
  759. ;   AL - status: 0=enabled, 1=disabled
  760. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  761. _setirqmask:
  762.         push ax bx cx dx
  763.         mov cl,bl
  764.         mov bx,0fffeh
  765.         movzx dx,al
  766.         rol bx,cl
  767.         shl dx,cl
  768.         in al,0a1h
  769.         mov ah,al
  770.         in al,21h
  771.         and ax,bx
  772.         or ax,dx
  773.         out 21h,al
  774.         mov al,ah
  775.         out 0a1h,al
  776.         pop dx cx bx ax
  777.         ret
  778. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  779. ; Set a real mode IRQ vect to redirect to pmode
  780. ; In:
  781. ;   BL - IRQ number
  782. ;   EDX - offset of IRQ handler
  783. ;   EDI -> 21 byte buffer for code stub created
  784. ; Out:
  785. ;   EAX - old seg:off of real mode IRQ handler
  786. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  787. rmpmirqsetd0:
  788. db 66h,52h              ; PUSH EDX
  789. db 66h,0bah,?,?,?,?     ; MOV EDX,?
  790. db 0cdh,32h             ; INT 32h
  791. db 66h,5ah              ; POP EDX
  792. db 0cfh                 ; IRET
  793. db 9ch                  ; PUSHFD
  794. db 0eh                  ; PUSH CS
  795. db 0e8h,?,?,?,?         ; CALL ?
  796. db 0c3h                 ; RET
  797. ;-----------------------------------------------------------------------------
  798. _rmpmirqset:
  799.         push esi edi
  800.         mov esi,offset rmpmirqsetd0
  801.         lea eax,[edi+13]
  802.         mov [esi+4],eax
  803.         add eax,7
  804.         sub eax,edx
  805.         neg eax
  806.         mov [esi+16],eax
  807.         mov eax,edi
  808.         movsd
  809.         movsd
  810.         movsd
  811.         movsd
  812.         movsd
  813.         movsb
  814.         add eax,_code32a
  815.         shl eax,12
  816.         shr ax,12
  817.         movzx edi,bl
  818.         cmp edi,8
  819.         jb short rmpmirqsetf0
  820.         add edi,60h
  821. rmpmirqsetf0:
  822.         xchg eax,gs:[edi*4+20h]
  823.         pop edi esi
  824.         ret
  825. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  826. ; Reset a real more IRQ vect back to normal (just sets real mode IRQ vect)
  827. ; In:
  828. ;   BL - IRQ number
  829. ;   EAX - seg:off of real mode IRQ handler
  830. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  831. _rmpmirqfree:
  832.         push ebx
  833.         movzx ebx,bl
  834.         cmp bl,8
  835.         jb short rmpmirqfreef0
  836.         add bl,60h
  837. rmpmirqfreef0:
  838.         mov gs:[ebx*4+20h],eax
  839.         pop ebx
  840.         ret
  841. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  842. ; Allocate a selector
  843. ; Out:
  844. ;   CF=1 - selector not allocated
  845. ;   CF=0 - selector allocated
  846. ;   AX - 4G data selector or ?
  847. ; Notes:
  848. ;   The selector returned is for a 4G r/w data segment with an undefined base
  849. ;    address.
  850. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  851. _getselector:
  852. if SELECTORS eq 0
  853.         stc
  854.         ret
  855. else
  856.         push ecx edi
  857.         mov edi,offset selectorfree
  858.         mov ecx,SELECTORS
  859.         mov al,0
  860.         repne scasb
  861.         jne short getselectorf0
  862.         mov byte ptr [edi-1],1
  863.         sub ecx,SELECTORS-1
  864.         neg ecx
  865.         imul cx,selectorinc
  866.         mov ax,selectorbase
  867.         add ax,cx
  868.         clc
  869.         jmp short getselectorf1
  870. getselectorf0:
  871.         stc
  872. getselectorf1:
  873.         pop edi ecx
  874.         ret
  875. endif
  876. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  877. ; Free an allocated selector
  878. ; In:
  879. ;   AX - selector
  880. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  881. _freeselector:
  882. if SELECTORS ne 0
  883.         push eax dx
  884.         sub ax,selectorbase
  885.         xor dx,dx
  886.         div selectorinc
  887.         movzx eax,ax
  888.         mov selectorfree[eax],0
  889.         pop dx eax
  890. endif
  891.         ret
  892. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  893. ; Exit to real mode
  894. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  895. _exit:
  896.         cli
  897.         mov eax,oint1bvect              ; restore ctrl+break
  898.         mov gs:[1bh*4],eax
  899.         mov eax,oint32vect              ; restore real mode int 32h vector
  900.         mov gs:[32h*4],eax
  901.         mov ax,oirqmask                 ; restore PIC masks
  902.         out 0a1h,al
  903.         mov al,ah
  904.         out 21h,al
  905.         push code16sel                  ; go to 16bit pmode exit code
  906.         push code16off
  907.         mov ds,data16sel
  908.         db 66h,0cbh             ; 16bit RETF
  909.  
  910. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  911. ; 32 bit DPMI system data
  912. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  913. dp_switchaddx   df      ?               ; switch to real mode addx
  914. dp_saveaddx     df      ?               ; save/restore state addx
  915. dp_savelen      dw      0,0             ; length of state buffer
  916. dp_savedstakoff dd      ?               ; current saved stack offset
  917. dp_savedstaksel dw      ?               ; current saved stack selector
  918.  
  919. dp_ointbuf      df      20 dup(?)       ; saved interrupt addx buffer
  920. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  921. ; 32 bit DPMI system code
  922. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  923. ;═════════════════════════════════════════════════════════════════════════════
  924. dp_int32:                               ; DPMI INT32/34: CX:DX=seg:off
  925.         pushad
  926.         shl ecx,16
  927.         mov cx,dx
  928.         mov bp,offset callreal
  929.         mov dl,1
  930.         jmp short dp_int3_
  931. ;═════════════════════════════════════════════════════════════════════════════
  932. dp_int33:                               ; DPMI INT33/35: AL=int num
  933.         pushad
  934.         movzx eax,al
  935.         mov ecx,gs:[eax*4]
  936.         mov bp,offset intreal
  937.         xor dl,dl
  938. ;-----------------------------------------------------------------------------
  939. dp_int3_:                               ; DPMI int or call to real mode
  940.         mov ax,900h
  941.         int 31h
  942.         push ax
  943.         and al,dl
  944.         add al,0fah
  945.         mov ebx,_code16a
  946.         mov gs:icrealm0[ebx],al
  947.         mov gs:icrealm1[ebx],ecx
  948.         push dp_savedstakoff
  949.         push dp_savedstaksel
  950.         movzx ebx,nextmodestack
  951.         lea eax,[ebx-STAKRMODE*16]
  952.         mov nextmodestack,ax
  953.         mov ax,ss
  954.         mov es,ax
  955.         sub esp,dword ptr dp_savelen
  956.         mov edi,esp
  957.         xor al,al
  958.         call dp_saveaddx
  959.         mov dp_savedstakoff,esp
  960.         mov dp_savedstaksel,ss
  961.         mov dx,codeend
  962.         mov ax,v86r_ds
  963.         mov cx,v86r_es
  964.         movzx edi,bp
  965.         mov si,code16
  966.         jmp dp_switchaddx
  967. ;-----------------------------------------------------------------------------
  968. dp_int3_d:                              ; done with real mode int or call
  969.         mov edi,esp
  970.         mov al,1
  971.         call dp_saveaddx
  972.         add esp,dword ptr dp_savelen
  973.         pop dp_savedstaksel
  974.         pop dp_savedstakoff
  975.         add nextmodestack,STAKRMODE*16
  976.         mov bx,v86r_flags
  977.         pop ax
  978.         int 31h
  979.         mov ax,ds
  980.         mov es,ax
  981.         mov fs,ax
  982.         mov gs,_selzero
  983.         mov ax,[esp+40]
  984.         and ax,not 8d5h
  985.         and bx,8d5h
  986.         or ax,bx
  987.         mov [esp+40],ax
  988.         popad
  989.         iretd
  990. ;═════════════════════════════════════════════════════════════════════════════
  991. ; DPMI IRQ redirectors (needed to make all IRQ vector selectors = CS)
  992. dp_irq0:
  993.         jmp cs:dp_ointbuf[0]
  994. dp_irq1:
  995.         jmp cs:dp_ointbuf[6]
  996. dp_irq2:
  997.         jmp cs:dp_ointbuf[12]
  998. dp_irq3:
  999.         jmp cs:dp_ointbuf[18]
  1000. dp_irq4:
  1001.         jmp cs:dp_ointbuf[24]
  1002. dp_irq5:
  1003.         jmp cs:dp_ointbuf[30]
  1004. dp_irq6:
  1005.         jmp cs:dp_ointbuf[36]
  1006. dp_irq7:
  1007.         jmp cs:dp_ointbuf[42]
  1008. dp_irq8:
  1009.         jmp cs:dp_ointbuf[48]
  1010. dp_irq9:
  1011.         jmp cs:dp_ointbuf[54]
  1012. dp_irqa:
  1013.         jmp cs:dp_ointbuf[60]
  1014. dp_irqb:
  1015.         jmp cs:dp_ointbuf[66]
  1016. dp_irqc:
  1017.         jmp cs:dp_ointbuf[72]
  1018. dp_irqd:
  1019.         jmp cs:dp_ointbuf[78]
  1020. dp_irqe:
  1021.         jmp cs:dp_ointbuf[84]
  1022. dp_irqf:
  1023.         jmp cs:dp_ointbuf[90]
  1024.  
  1025. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1026. ; DPMI get IRQ handler offset
  1027. ; In:
  1028. ;   BL - IRQ num (0-0fh)
  1029. ; Out:
  1030. ;   EDX - offset of IRQ handler
  1031. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1032. dp_getirqvect:
  1033.         push ax ebx cx
  1034.         movzx ebx,bl
  1035.         mov bl,intslottbl[ebx]
  1036.         mov ax,204h
  1037.         int 31h
  1038.         pop cx ebx ax
  1039.         ret
  1040. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1041. ; DPMI set IRQ handler offset
  1042. ; In:
  1043. ;   BL - IRQ num (0-0fh)
  1044. ;   EDX - offset of IRQ handler
  1045. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1046. dp_setirqvect:
  1047.         push ax ebx cx
  1048.         movzx ebx,bl
  1049.         mov bl,intslottbl[ebx]
  1050.         mov cx,cs
  1051.         mov ax,205h
  1052.         int 31h
  1053.         pop cx ebx ax
  1054.         ret
  1055. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1056. ; Set the base addx for a selector
  1057. ; In:
  1058. ;   AX - selector
  1059. ;   EDX - linear base addx for selector
  1060. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1061. dp_setselector:
  1062. if SELECTORS ne 0
  1063.         push ax bx ecx
  1064.         shld ecx,edx,16
  1065.         mov bx,ax
  1066.         mov ax,7
  1067.         int 31h
  1068.         pop ecx bx ax
  1069. endif
  1070.         ret
  1071.  
  1072. code32  ends
  1073.  
  1074. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  1075. ; End of program (must be at end of program or you will suffer)
  1076. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  1077. codeend segment para stack use32 'stack'
  1078. db STAKSIZE*16 dup(?)
  1079. codeend ends
  1080.         end     start16
  1081.  
  1082.